package cn.com.callback

import cn.com.elite.EliteBean
import cn.com.elite.Util
import cn.com.kh.KHDBConfig
import cn.com.kh.KHUtil

import net.sf.json.JSONObject
import org.bouncycastle.asn1.pkcs.RSAPrivateKey
import org.bouncycastle.openssl.PEMParser
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.jdbc.core.JdbcTemplate

import javax.crypto.BadPaddingException
import javax.crypto.Cipher
import javax.crypto.IllegalBlockSizeException
import javax.crypto.NoSuchPaddingException
import javax.crypto.spec.OAEPParameterSpec
import javax.crypto.spec.PSource
import javax.naming.CommunicationException
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse
import java.nio.charset.StandardCharsets
import java.security.GeneralSecurityException
import java.security.InvalidAlgorithmParameterException
import java.security.InvalidKeyException
import java.security.Key
import java.security.KeyFactory
import java.security.KeyPair
import java.security.KeyPairGenerator
import java.security.NoSuchAlgorithmException
import java.security.PrivateKey
import java.security.PublicKey
import java.security.Signature
import java.security.interfaces.RSAPublicKey
import java.security.spec.InvalidKeySpecException
import java.security.spec.MGF1ParameterSpec
import java.security.spec.PKCS8EncodedKeySpec
import java.security.spec.RSAPrivateKeySpec
import java.security.spec.X509EncodedKeySpec


/**
 * @Title: apiSendEmail*
 * @Description: 对接平安期货邮件服务
 * @author: TaoHao
 * @date 2025-04-21
 */

class apiSendEmail implements ServiceBackInvoke {

    private static final Logger log = LoggerFactory.getLogger(apiSendEmail.class);
    private static String Mail_Url; // #请求地址"http://10.17.1.27:8003/api/sendMail"
    private static String Mail_Key;
    // #加密Key '-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAoiDVkphNOthiTrPzIMkSImYvD6bsgSH2cy1LM0NdnFg0kMM2DuNEKSTi+2gEu6XS/IoN1aQQ3BrFLsoGSt4GIfMJ8DYXvO8diktEJFAsZ+KegMgGWAMGcCk9gFy+QTE15hqw4HHDTAzuxqCFkxVYtiGf3ExqIF3cLC3+1FBva/MCu8OqB0/CUKsVWYxbh+C3F0dORVILbRCTdEZQz0VxtGV5b/mG86lD2uKFK3LhYyogKyiUD3donRwfLr8a3Q6BAWXqUoU7YX8fY3gQTmYJiTx3SfaE6pKBrCy/lcvmVWkYbsM0/V4ZduPWuy6o2REz0tppNOeZsJFsKfIj0tdbXQIDAQAB\n-----END PUBLIC KEY-----'
    // 加密算法
    private final static String ALGORITHM_RSA = "RSA";

    private final static String ALGORITHM_OAEP = "RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING";

    public static String rsaPublicKey;

    public static String rsaPrivateKey;
    public static  JdbcTemplate jt;
    /**
     * 密钥长度 于原文长度对应 以及越长速度越慢
     */
    private final static int KEY_SIZE = 2048;
    /**
     * 用于封装随机产生的公钥与私钥
     */
    static Map<Integer, String> keyMap = new HashMap<Integer, String>();


    @Override
    String doCallBack(EliteBean eliteBean, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        httpServletResponse.setCharacterEncoding("UTF-8");
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        jt=new JdbcTemplate(eliteBean.getDataSource());
        // 获取接口调用方式及参数
        String getMethod = httpServletRequest.getMethod();
        log.debug("[getMethod]:" + getMethod);

        JSONObject result = new JSONObject();
        String inData = "";
        if (getMethod.equals("GET")) {
            inData = httpServletRequest.getParameter("data");
            log.debug("[原始Get请求参数]:" + inData);
        } else {
            InputStreamReader reader = new InputStreamReader(httpServletRequest.getInputStream(), "UTF-8");
            BufferedReader iny = new BufferedReader(reader);
            String line;
            while ((line = iny.readLine()) != null) {
                inData += line;
            }
            log.debug("[原始Post请求参数]:" + inData);
        }
        log.info("[调用请求信息]:" + inData);


        try {
            if (KHUtil.isNull(inData)) {
                log.error("【apiSendEmail】调用参数为空！");
                result.put("code", "-1");
                result.put("msg", "【apiSendEmail】调用参数为空！");
                return result.toString();
            }

            org.json.JSONObject dataJson = new org.json.JSONObject(inData);
            String receiveAddressArray = KHUtil.GetJV(dataJson, "receiveAddressArray");//发送给的邮件人 数组 1,2
            String subject = KHUtil.GetJV(dataJson, "subject");//邮件主题
            String content = KHUtil.GetJV(dataJson, "content");//邮件内容
            String from = KHUtil.GetJV(dataJson, "from");//发送人邮件
            String mailAccount = KHUtil.GetJV(dataJson, "mailAccount");//发送人账号  注意不要带后缀:@pingan.com.cn
            String mailPassword = KHUtil.GetJV(dataJson, "mailPassword");//发送人密钥
            String ccAddressArray = KHUtil.GetJV(dataJson, "ccAddressArray");//抄送人数组  1,2
            String workorderid = KHUtil.GetJV(dataJson, "workorderid");//工单ID
            String Type = KHUtil.GetJV(dataJson, "type");//发送来源 1是工单
            String createdby = KHUtil.GetJV(dataJson, "createdby");//创建人
            String createdgrp = KHUtil.GetJV(dataJson, "createdgrp");//创建组

            if (KHUtil.isNull(receiveAddressArray)) {
                log.error("【apiSendEmail】调用参数为空！");
                result.put("code", "-1");
                result.put("msg", "【apiSendEmail】发送给的邮件人不能为空！");
                return result.toString();
            } else if (KHUtil.isNull(subject)) {
                log.error("【apiSendEmail】调用参数为空！");
                result.put("code", "-1");
                result.put("msg", "【apiSendEmail】邮件主题不能为空！");
                return result.toString();
            } else if (KHUtil.isNull(content)) {
                log.error("【apiSendEmail】调用参数为空！");
                result.put("code", "-1");
                result.put("msg", "【apiSendEmail】邮件内容不能为空！");
                return result.toString();
            } else if (KHUtil.isNull(from)) {
                log.error("【apiSendEmail】调用参数为空！");
                result.put("code", "-1");
                result.put("msg", "【apiSendEmail】发送人邮件不能为空！");
                return result.toString();
            } else if (KHUtil.isNull(mailAccount)) {
                log.error("【apiSendEmail】调用参数为空！");
                result.put("code", "-1");
                result.put("msg", "【apiSendEmail】发送人账号不能为空！");
                return result.toString();
            }


            Mail_Url = KHDBConfig.getAPIURL(eliteBean, "Mail_Url");//查询配置的邮箱接口地址

            if (KHUtil.isNull(Mail_Url)) {
                log.error("【apiSendEmail】未查询到配置的邮箱接口地址！");
                result.put("code", "-1");
                result.put("msg", "【apiSendEmail】未查询到配置的邮箱接口地址！");
                return result.toString();
            }
            Mail_Key = KHDBConfig.getParam(eliteBean, "Em-Key");//查询配置的密钥
            if (KHUtil.isNull(Mail_Key)) {
                log.error("【apiSendEmail】未查询到配置的邮箱加密密钥！");
                result.put("code", "-1");
                result.put("msg", "【apiSendEmail】未查询到配置的邮箱加密密钥！");
                return result.toString();
            }


            String encryptedText = encrypt(mailPassword, Mail_Key);

            log.debug("【apiSendEmail】加密密钥:" + encryptedText);

            JSONObject requse_body = new JSONObject();//发送请求报文

            requse_body.put("bsendOrsave", 1);//bsendOrsave 保存或直接发送  1:直接发送 0:保存到草稿箱
            requse_body.put("subject", subject);//邮件主题
            requse_body.put("content", content);//邮件内容
            requse_body.put("from", from + "@pingan.com.cn");//发送人
            requse_body.put("mailAccount", mailAccount);//发送人账号
            requse_body.put("mailPassword", encryptedText);//发送人密钥
            requse_body.put("receiveAddressArray", receiveAddressArray.split(","));//发送给的邮件人
            requse_body.put("ccAddressArray", ccAddressArray.split(","));//抄送给的邮件人
            requse_body.put("attachmentFiles", []);//发送附件
            // 处理头文件
            Map<String, String> headerMap = new HashMap<String, String>();

            headerMap.put("Accept", "application/json");

            headerMap.put("Content-Type", "application/json");

            log.debug("【apiSendEmail】调用PAQH发送邮件接口地址:" + Mail_Url);

            log.debug("【apiSendEmail】调用PAQH发送邮件接口报文:" + requse_body.toString());

            String Requst_Post = Util.doHttpPostUseHead(Mail_Url, requse_body.toString(), "UTF-8", 80000, 0, headerMap);

            log.debug("【apiSendEmail】调用PAQH发送邮件接口返回:" + Requst_Post.toString());

            org.json.JSONObject Requst_Post_Json = new org.json.JSONObject(Requst_Post);

            if (KHUtil.GetJV(Requst_Post_Json, "code") == "0") {
                result.put("code", "1");
                result.put("msg", "【apiSendEmail】邮件发送成功!");
                InsertSendList(Type,KHUtil.GetJV(Requst_Post_Json, "code") , subject, content,
                         receiveAddressArray,
                                 ccAddressArray,mailAccount,workorderid,Requst_Post, createdby, createdgrp)
            } else {
                result.put("code", "-1");
                result.put("msg", "【apiSendEmail】邮件发送失败，请联系系统管理员查看相关日志:" + Requst_Post);
            }


        } catch (Exception e1) {
            log.error("【apiSendEmail】调用Pa邮件发送异常：", e1);
            result.put("code", "-1");
            result.put("msg", "【apiSendEmail】调用Paqh邮件发送异常:" + e1);
        }
        return result.toString();
    }

    /**
     * RSA公钥加密
     *
     * @param str 加密字符串
     * @param publicKey 公钥
     * @return 密文
     * @throws Exception 加密过程中的异常信息
     */
    public static String encrypt(String str, String publicKey) {
        log.info("RSAUtils encrypt, str:{}, publicKey:{}", str, publicKey);
        //base64编码的公钥
        byte[] decoded = decryptBASE64(publicKey);
        RSAPublicKey pubKey = null;
        try {
            pubKey = (RSAPublicKey) KeyFactory.getInstance(ALGORITHM_RSA).generatePublic(new X509EncodedKeySpec(decoded));
        } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
            log.error("[KeyFactory getInstance generatePublic  error, e:", e);
        }
        Cipher cipher = InitAndGetRSACipher(Cipher.ENCRYPT_MODE, pubKey);
        String outStr = encryptBASE64(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));

        log.info("[RSAUtils encrypt], outStr:{}", outStr);
        return outStr;
    }

    /**
     * RSA私钥解密
     *
     * @param str 加密字符串
     * @param privateKey 私钥
     * @return 明文
     */
    public static String decrypt(String str, String privateKey) {
        log.info("RSAUtils decrypt start, str:{}, privateKey:{}", str, privateKey);
        //64位解码加密后的字符串
        byte[] inputByte = decryptBASE64(str);
        //base64编码的私钥
        byte[] decoded = decryptBASE64(privateKey);
        String outStr;
        try {
            java.security.interfaces.RSAPrivateKey priKey = (java.security.interfaces.RSAPrivateKey) KeyFactory.getInstance(ALGORITHM_RSA).generatePrivate(new PKCS8EncodedKeySpec(decoded));
            //RSA解密
            Cipher cipher = InitAndGetRSACipher(Cipher.DECRYPT_MODE, priKey);
            outStr = new String(cipher.doFinal(inputByte));
        } catch (InvalidKeySpecException | NoSuchAlgorithmException | IllegalBlockSizeException | BadPaddingException e) {
            log.error("[RSAUtils decrypt  error, e:", e);

        }
        return outStr;
    }

    public static Cipher InitAndGetRSACipher(int modeType, Key rsaKey) {
        Cipher cipher;
        try {
            cipher = Cipher.getInstance(ALGORITHM_OAEP);
            OAEPParameterSpec oaepParameterSpec = new OAEPParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, PSource.PSpecified.DEFAULT);
            cipher.init(modeType, rsaKey, oaepParameterSpec);
            log.info("provider:{}", cipher.getProvider().getClass().getName());
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException e) {
            log.error("[Cipher init  error, e:", e);

        }
        return cipher;
    }



    public static  int InsertSendList(String Type,String Status,String subject,String content,
                                         String receiveAddressArray,
                                         String ccAddressArray,String mailAccount,String workorderid,String send_body,String createdby,String createdgrp){

        String InsertSql='''Insert into pa_email_send_list(Rec_guid,Type,Status,Email_subject,documentpath,
Email_Receive_List,Email_CS_Receive_List,Email_Send,workorderid,Send_response_body,Created_by,Created_GRP,Send_date)
values(uuid(),?,?,?,?,?,?,?,?,?,?,?,now())
''';
        int insertrow=jt.update(InsertSql,Type,Status,subject,content,receiveAddressArray,ccAddressArray,mailAccount,workorderid,send_body,createdby,createdgrp);


        log.debug("【apiSendEmail】新增邮件发送历史表数量:"+insertrow);

        return insertrow;
    }


    /**
     * 随机生成密钥对
     */
    public static void genKeyPair() {
        // KeyPairGenerator类用于生成公钥和私钥对，基于RSA算法生成对象
        KeyPairGenerator keyPairGen = null;
        try {
            keyPairGen = KeyPairGenerator.getInstance(ALGORITHM_RSA);
        } catch (NoSuchAlgorithmException e) {
            log.error("[KeyPairGenerator getInstance error, e:", e);

        }
        // 初始化密钥对生成器
        keyPairGen.initialize(KEY_SIZE);
        // 生成一个密钥对，保存在keyPair中
        KeyPair keyPair = keyPairGen.generateKeyPair();
        // 得到私钥
        java.security.interfaces.RSAPrivateKey privateKey = (java.security.interfaces.RSAPrivateKey) keyPair.getPrivate();
        // 得到公钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        String publicKeyString = encryptBASE64(publicKey.getEncoded());
        rsaPublicKey = publicKeyString;
        // 得到私钥字符串
        String privateKeyString = encryptBASE64(privateKey.getEncoded());
        rsaPrivateKey = privateKeyString;
        // 将公钥和私钥保存到Map
        //0表示公钥
        keyMap.put(0, publicKeyString);
        //1表示私钥
        keyMap.put(1, privateKeyString);
        //log.info("[RSAUtils genKeyPair], keyMap:{}", keyMap);
    }

    //编码返回字符串
    public static String encryptBASE64(byte[] key) {
        return new String(Base64.getEncoder().encode(key));
    }

    //解码返回byte
    public static byte[] decryptBASE64(String key) {
        return Base64.getDecoder().decode(key);
    }
}
